class Page{
    constructor(id){
		this.id = id;
		this.data = Page.initData;
		this.modified = false;
	}
	
	loadPageData(callback){
	    let page = this;
		$.ajax({
			type: 'GET',
			url : '/page/data',
            data: {
			    id: this.id
            },
			dataType: 'text',
            cache: false,
			success: function (data) {
			    page.data = data;
				callback(data, true);
            },
			error: function (o) {
				callback(getAjaxErrorMsg(o), false);
            }
		});
	}

    save(data){
		if(this.data !== data){
			this.data = data;
			this.modified = true;
			console.log("save changes");
		}
	}

	saveOnline(callback){
        const page = this;
        if(user.logged && this.id && page.modified){
            $.ajax({
                type: 'POST',
                url: '/page/update',
                data: {
                    id: page.id,
                    data: page.data
                },
                success: function (json) {
                    page.modified = false;
                    callback(true);
                },
                error: function (o) {
                    callback(false);
                }
            });
        }else {
            callback(true);
        }
    }

	getData(){
		return this.data;
	}

	isModified(){
		return this.modified;
	}
}
Page.initData = '{"version":"2.2.3","objects":[],"background":"#fcfcfc"}';

class Doc{
	constructor(id, name, createTime){
		this.id = id;
		this.createTime = createTime;
		this.pages = [null]; //[page, page],第0页占位
		this.name = name ? name : '新建白板文档' + Math.random().toString(10).substr(2, 6);
		this.pageLoaded = false;
		this.newCreate = false;
	}
	
	rename(newName, callback){
		const doc = this;
		$.ajax({
            type: 'POST',
            url: '/document/rename',
            data:{
            	id: this.id,
            	name: newName
			},
            success: function (object) {
				doc.name = newName;
                callback(object.msg, true);
            },
            error: function (o) {
                callback(getAjaxErrorMsg(o), false);
            }
		});
	}
	
	deleteSelf(callback){
		const doc = this;
        $.ajax({
            type: 'POST',
            url: '/document/delete',
            data:{
                id: doc.id
            },
            success: function (object) {
                DocManager.docs[doc.id] = null;
                callback(object.msg, true);
            },
            error: function (o) {
                callback(getAjaxErrorMsg(o), false);
            }
        });
	}
	
	loadPages(callback){
	    console.log('load pages of doc :' + this.id);
        const doc = this;
        $.ajax({
            type: 'GET',
            url: '/page/list',
            data:{
                docId: doc.id
            },
            success: function (array) {
                array.forEach(function (object) {
					doc.pages[object.pageNum] = new Page(object.pageId);
                });
                doc.pageLoaded = true;
                callback(doc.pages, true);
            },
            error: function (o) {
                callback(getAjaxErrorMsg(o), false);
            }
        });
	}
	
	saveAllPages(callback){
	    let doc = this;
	    //如果是本地文档,则新建这个文档并同步页面数据
        if(doc.id === null){
            console.log("本地同步");
            let name = '同步的本地白板文档' + Math.random().toString(10).substr(2, 6);
            let pageData = [];
            for(let i=1; i<doc.pages.length; i++){
                pageData.push(doc.pages[i].getData());
            }
            console.log('size: ' + pageData.length);
            $.ajax({
                type: 'POST',
                url: '/document/sync',
                data: {
                    name: name,
                    pageData: JSON.stringify(pageData)
                },
                success: function (docPages) {
                    console.log(docPages);
                    doc.id = docPages.doc.docId;
                    doc.name = docPages.doc.docName;
                    doc.createTime = docPages.doc.docCreateTime;
                    docPages.pages.forEach(function (page) {
                        let mPage = doc.getPage(page.pageNum);
                        mPage.id = page.pageId;
                        mPage.url = page.pageUrl;
                        mPage.modified = false;
                    });
                    doc.pageLoaded = true;
                    DocManager.docs[doc.id] = doc;
                    DocManager.initDoc = new Doc(null, "本地白板文档", (new Date()).toLocaleString()).addPage(1);
                    DocManager.initDoc.getPage(1).modified = false;
                    callback('文档已同步到您的账户', true);
                },
                error: function (o) {
                    callback(getAjaxErrorMsg(o), false);
                }
            });
        }else {
            console.log('保存在线文档');
            let count = 1;
            for (let i=1; i<doc.pages.length; i++){
                doc.getPage(i).saveOnline(function (success) {
                    if(!success){
                        callback("文档第" + i +"页保存失败了", false);
                        return;
                    }
                    count++;
                    if(count === doc.pages.length){
                        callback('文档已保存到您的账户', false);
                    }
                });
            }
        }
	}
	
	getPage(num){
		return this.pages[num];
	}
	
	addPage(num){
	    let page = new Page(null);
        this.pages.splice(num, 0, page);
        page.modified = true;
	    if(user.logged && this.id){
            $.ajax({
                type: 'POST',
                url: '/page/create',
                data: {
                    num: num,
                    docId: this.id
                },
                success: function (json) {
                    page.id = json.pageId;
                    // page.url = json.pageUrl;
                },
                error: function (o) {
                    showInfo(getAjaxErrorMsg(o));
                }
            });
        }
		return this;
	}

	deletePage(num, callback){
	    let doc = this;
	    if(doc.pages.length === 2){
	        //这是文档唯一一页，不做删除，直接清空页面
            doc.getPage(1).save(Page.initData);
            doc.getPage(1).saveOnline(callback);
        }else {
	        //不是唯一一页，直接删除
	        if(doc.id === null){
	            //本地文档
                doc.pages.splice(num, 1);
                callback(true);
            }else {
	            let id = this.getPage(num).id;
	            //在线文档
                $.ajax({
                    type: 'POST',
                    url: '/page/delete',
                    data: {
                        id: id
                    },
                    success: function (json) {
                        doc.pages.splice(num, 1);
                        callback(true);
                    },
                    error: function (o) {
                        callback(false);
                    }
                });
            }
        }
	}

	isModified(){
		for(let i=1; i<this.pages.length; i++){
			if(this.pages[i].isModified())
				return true;
		}
		return false;
	}
}

class DocManager{
	static loadMyDocs(callback){
		$.ajax({
			type: 'GET',
			url: '/document/list',
			success: function (array) {
				DocManager.docs = [];

				const docSequence = [];
				let doc = null;
				for(let i=0; i<array.length; i++){
                    doc = new Doc(array[i].docId, array[i].docName, array[i].docCreateTime);
                    DocManager.docs[array[i].docId] = doc;
                    docSequence.push(doc);
				}
				callback(docSequence, true);
            },
			error: function (o) {
				callback(getAjaxErrorMsg(o), false);
            }
		});
	}
	
	static getDoc(id){
		return DocManager.docs[id];
	}
	
	static createDoc(name, callback){
		$.ajax({
			type: 'POST',
			url: '/document/create',
			data:{name: name},
			success: function (object) {
                let doc = new Doc(object.docId, object.docName, object.docCreateTime);
                doc.newCreate = true;
                DocManager.docs[object.docId] = doc;
                callback(doc, true);
            },
			error: function (o) {
				callback(getAjaxErrorMsg(o), false);
            }
		});
	}
	
}
DocManager.docs = [];
DocManager.initDoc = new Doc(null, "本地白板文档", (new Date()).toLocaleString()).addPage(1);
DocManager.initDoc.getPage(1).modified = false;
DocManager.currentDoc = DocManager.initDoc;

document.getElementById('file-name').innerHTML = DocManager.currentDoc.name;

//将文档数组加载到列表界面
function setFilesTable(docSequence){
    const tbody = document.querySelector('#files-table tbody');
    tbody.innerHTML = '';
    for(let i=0; i<docSequence.length; i++){
        tbody.innerHTML += createFileRow(docSequence[i]);
    }
    //添加提示工具
    const btns = $(".file-operation [data-toggle='tooltip']");
    btns.tooltip({'trigger':'hover'});
    //点击时隐藏提示
    btns.click(function () {
        $(this).tooltip('hide');
    });
}

//处理新建文档按钮的点击
$('#new-file-btn').click(function(){
	bootbox.prompt({
		title : '请输入文档名',
		value: '新建白板文档'+ Math.random().toString(10).substr(2, 6),
		buttons: {
			cancel: {label: '取消'},
			confirm: {label: '新建'}
		},
		callback: function (result) {
			if(result === null)
				return;
			result = $.trim(result);
			if(result.length === 0)
				return;
			DocManager.createDoc(result, function (data, success) {
				if(success){
                    insertOneDoc(data);
				}else {
					showInfo(data);
				}
            })
		}
	});
});

//处理打开文档的点击
function fileOpenClick(docId) {
    if(DocManager.currentDoc.id === docId){
        showInfo("该文档正是当前打开的文档");
        return;
    }
	if(DocManager.currentDoc.isModified()){
        bootbox.confirm({
            title: "当前文档未保存",
            message: "确认打开新文档，并放弃当前更改吗？",
            buttons: {
                confirm: {
                    label: '确认打开',
                    className: 'btn-danger'
                },
                cancel: {
                    label: '返回保存',
                    className: 'btn-success'
                }
            },
            callback: function (result) {
                if(!result) return;
				openDoc(docId);
            }
        });
	}else
		openDoc(docId);
}


function openDoc(docId) {
    docLoading();
    const doc = DocManager.getDoc(docId);
    if(doc.pageLoaded){
        renderFirstPage(doc);
        return;
    }
    doc.loadPages(function (pages, success) {
        if(success){
            //若是新建的文档，则不请求页面数据直接加载空页
            if(doc.newCreate){
                renderFirstPage(doc);
                return;
            }
            //若不是新文档，加载第一页并渲染到界面
            pages[1].loadPageData(function (data, success) {
                console.log('加载在线文档的第一页');
                if(success){
                    renderFirstPage(doc);
                }else {
                    showInfo(data);
                    docLoaded();
                }
            });
            //加载剩余页面数据
            for(let i=2; i<pages.length; i++){
                pages[i].loadPageData(function (data, success) {
                    if(!success){
                        showInfo("加载第" + i + "页数据失败：" + data);
                    }
                });
            }
        }else {
            showInfo(pages);
        }
    });
}

function renderFirstPage(doc) {
    DocManager.currentDoc = doc;
    fileName.text(doc.name);
    renderJson(doc.getPage(1).getData());
    currentPageNumber.text(1);
    totalPageNumber.text(doc.pages.length - 1);
    $('#files-fragment').hide('fast');
    docLoaded();
    showInfo("已打开 < " + doc.name + " > ");
}

//处理文档重命名的点击
function fileRenameClick(docId){
	console.log(docId);
	const doc = DocManager.getDoc(docId);
	bootbox.prompt({
		title : '请输入文档名',
		value: doc.name,
		buttons: {
			cancel: {label: '取消'},
			confirm: {label: '重命名'}
		},
		callback: function (result) {
			if(result === null)
				return;
			result = $.trim(result);
			if(result.length ===0 || result === doc.name)
				return;
			doc.rename(result, function (msg, success) {
				if(success){
					$('#'+docId).find('.file-name').text(result);
					fileName.text(result);
				}else {
					showInfo(msg);
				}
            });
		}
	});
}

//处理删除文档的点击
function fileDeleteClick(docId){
	bootbox.confirm({
		title: "确认删除文档?",
		message: "注意：删除后无法恢复",
		buttons: {
			confirm: {
				label: '确认',
				className: 'btn-danger'
			},
			cancel: {
				label: '取消',
				className: 'btn-success'
			}
		},
		callback: function (result) {
			if(!result) return;
			const current = DocManager.currentDoc;
			const toDelete = DocManager.getDoc(docId);
			toDelete.deleteSelf(function (msg, success) {
				if(success){
					const tr = document.getElementById(docId);
					tr.parentNode.removeChild(tr);
					if(current === toDelete){
					    DocManager.currentDoc = DocManager.initDoc;
					    renderFirstPage(DocManager.currentDoc);
                    }
				}else {
					showInfo(msg);
				}
            });
		}
	});
}

//创建一个文档对应的表格行
function createFileRow(doc) {
    return `<tr id="${doc.id}"> 
				<td class="file-name" onclick="fileOpenClick('${doc.id}')">${doc.name}</td> 
				<td class="file-time">${doc.createTime}</td> 
				<td class="file-operation"> 
				<span class="icon-edit file-rename" title="" data-toggle="tooltip" data-placement="auto" 
					data-original-title="重命名" onclick="fileRenameClick('${doc.id}')"></span> 
				<span class="icon-delete file-delete" title="" data-toggle="tooltip" data-placement="auto" 
					data-original-title="删除" onclick="fileDeleteClick('${doc.id}')"></span> 
				</td> 
			</tr>`;
}

function insertOneDoc(doc) {
    const tbody = document.querySelector('#files-table tbody');
    tbody.innerHTML = createFileRow(doc) + tbody.innerHTML;
    //添加提示工具
    const btns = $(".file-operation [data-toggle='tooltip']");
    btns.tooltip({'trigger':'hover'});
    //点击时隐藏提示
    btns.click(function () {
        $(this).tooltip('hide');
    });
}

//保存文档点击处理
$('#doc-save').click(function(){
    DocManager.currentDoc.getPage(parseInt(currentPageNumber.text())).save(getCanvasJson());
    if(!user.logged){
        showInfo('您没有登录，登录后可保存到在线文档');
        return;
    }
    docLoading();
    DocManager.currentDoc.saveAllPages(function (msg, isNewDoc) {
        docLoaded();
		showInfo(msg);
		if(isNewDoc){
		    insertOneDoc(DocManager.currentDoc);
		    fileName.text(DocManager.currentDoc.name);
        }
    });
});